import json
import os

from flask import Blueprint, session, send_file
from flask import request, render_template, url_for, redirect
from werkzeug.utils import secure_filename


from apps.admin.models import UpdateRobotFirmwareRos, UpdateRobotFirmwareDrive
from apps.admin.utils import del_files, un_tar, ssh_shutdown, allowed_map_file, allowed_music_file, copyfile
from apps.user.models import User
from exts import db
from utils.auth import auth
from utils.is_admin import is_admin
from utils.md5 import md5

admin_bp = Blueprint('admin', __name__)
# # 获取根目录 用于保存图片用
basedir = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))


# 后台管理首页
@admin_bp.route('/admin_index')
@auth
def admin_index():
    username = session.get('username')
    # 获取所有数据
    ros_ret = UpdateRobotFirmwareRos.query.filter(UpdateRobotFirmwareRos.is_delete == False).all()
    print(ros_ret, '--------------')
    # 2022.11.6新增
    # 通过用户名
    is_ad = is_admin(username=username)

    return render_template('admin/admin_index.html', username=username, ros_ret=ros_ret, is_admin=is_ad)


# 机器人硬件
@admin_bp.route('/update_robot_firmware', methods=['GET', 'POST'])
@auth
def update_robot_firmware():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/update_robot_firmware.html', username=username, is_admin=is_ad)
    # 进行存数据库
    ret = request.files
    if not ret:
        print('这里是恢复ROS固件初始化.')
    if request.files.get('file_ros'):
        # 获取上传的ROS固件
        ros = request.files.get('file_ros')
        ros_name = ros.filename
        # 存放的路径
        path = basedir + "\\static\\r_files\\ros\\"
        # 图片path和名称组成图片的保存路径
        file_path = path + ros_name
        # 保存文件
        ros.save(file_path)
        mysql_path = '/static/r_files/ros/' + ros_name
        # 路径存数据库
        ros_obj = UpdateRobotFirmwareRos()
        ros_obj.ros_name = ros_name
        ros_obj.ros_path = mysql_path
        # 保存数据库
        db.session.add(ros_obj)
        db.session.commit()
        return redirect(url_for('admin.admin_index'))

        # 文件存服务器，或者存云仓库(cos(腾讯对象存储)/oss(阿里对象存储)/七牛云)
    if request.files.get('file_drive'):
        # 获取上传的上传驱动板固件
        drive = request.files.get('file_drive')
        drive_name = drive.filename
        # 存放的路径
        path = basedir + "\\static\\r_files\\ros\\"
        # 图片path和名称组成图片的保存路径
        file_path = path + drive_name
        # 保存文件
        drive.save(file_path)
        mysql_path = '/static/r_files/drive/' + drive_name
        # 路径存数据库
        drive_obj = UpdateRobotFirmwareDrive()
        drive_obj.drive_name = drive_name
        drive_obj.drive_path = mysql_path
        # 保存数据库
        db.session.add(drive_obj)
        db.session.commit()
        # 路径存数据库
        # 文件存服务器，或者存云仓库(cos(腾讯对象存储)/oss(阿里对象存储)/七牛云)
        return redirect(url_for('admin.admin_index'))

    if request.form.get('mode'):
        # 重启机器人
        pass
    return render_template('admin/update_robot_firmware.html', username=username)


# update_robot_firmware编辑
@admin_bp.route('/edit_robot_firmware/<int:id>', methods=['GET', 'POST'])
@auth
def edit_robot_firmware(id):
    if request.method == 'GET':
        # 根据id查询到数据,进行修改
        ros_obj = UpdateRobotFirmwareRos.query.get(id)
        # print(ros_obj, '--------ssssssss--------')
        return render_template('admin/edit_robot_firmware.html', ros_obj=ros_obj)
    # 修改
    ros_name = request.form.get('ros_name')
    ros_obj = request.files.get('file_ros')
    print(ros_obj, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    if ros_obj:
        ros = request.files.get('file_ros')
        ros_name = ros.filename
        # 存放的路径
        path = basedir + "\\static\\r_files\\ros\\"
        # 图片path和名称组成图片的保存路径
        file_path = path + ros_name
        # 保存文件
        ros.save(file_path)
        mysql_path = '/static/r_files/ros/' + ros_name
        # 路径存数据库
        ros_obj = UpdateRobotFirmwareRos.query.get(id)
        ros_obj.ros_name = ros_name
        ros_obj.ros_path = mysql_path
        # 保存数据库
        db.session.add(ros_obj)
        db.session.commit()
        return redirect(url_for('admin.admin_index'))

    else:
        ros_obj = UpdateRobotFirmwareRos.query.get(id)
        ros_obj.ros_name = ros_name
        # 保存数据库
        db.session.add(ros_obj)
        db.session.commit()
        return redirect(url_for('admin.admin_index'))


# update_robot_firmware删除
@admin_bp.route('/delete_edit_robot_firmware/<int:id>', methods=['GET', 'POST'])
@auth
def delete_edit_robot_firmware(id):
    if not id:
        return redirect(url_for('admin.admin_index'))
    ros_obj = UpdateRobotFirmwareRos.query.get(id)
    ros_obj.is_delete = True
    # 保存数据库
    db.session.add(ros_obj)
    db.session.commit()
    return redirect(url_for('admin.admin_index'))


# 机器人配置更新
@admin_bp.route('/update_robot_configuration', methods=['GET', 'POST'])
@auth
def update_robot_configuration():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/update_robot_configuration.html', username=username, is_admin=is_ad)


# 机器人地图
@admin_bp.route('/map_management_configuration', methods=['GET', 'POST'])
@auth
def map_management_configuration():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/map_management_configuration.html', username=username, is_admin=is_ad)


@admin_bp.route('/view_configure/')
@auth
def view_configure():
    import yaml
    # file_paths = os.environ.get("LYH_CONFIG") + "/"
    yaml_config = dict()
    json_config = dict()
    params = list()
    actions = list()
    try:
        # current_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        current_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

        print(current_path, '-----------')
        print(current_path + r"\ros_config.yaml", '-----------')
        # D:\pythonProject\flask_admin\ros_config.yaml
        # ros_config.yaml配置
        yaml.default_style = "\""
        with open(current_path + r"\ros_config.yaml", 'r', encoding='utf-8') as f:
            yaml_config = yaml.load(f, Loader=yaml.FullLoader)

        for i in yaml_config.items():
            value = str(i[1]).replace("\'", "\"").replace("True", "true").replace("False", "false")
            temp = [i[0], value]
            params.append(temp)

        return render_template('cms/view_configure.html', params=params)

    except Exception as e:
        return render_template('cms/view_configure.html', params=[["error", str(e)]])


@admin_bp.route('/save_configure', methods=['POST'])
def save_configure():
    import yaml, json
    print('1')
    data = {
        "msg": "ok",
        "code": 0
    }

    try:
        req_data = request.form.to_dict()
        for key in req_data:
            req_data[key] = json.loads(req_data[key])
        current_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        # with open(current_path + "/configureServer/config/ros_config.yaml", 'w') as f:
        with open(current_path + r"\ros_config.yaml", 'w') as f:
            yaml.dump(req_data, f, allow_unicode=True, sort_keys=False)
        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}
    except BaseException as e:
        # print e

        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 恢复ros固件初始化
@admin_bp.route('/initialization_ros_firmware', methods=['POST'])
def initialization_ros_firmware():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        save_paths = os.environ.get("LYH_CONFIG") + "/"
        extract_path = os.environ.get("LYH_CONFIG") + "/../../ros_ws/"
        del_files(extract_path + "install_isolated")
        un_tar(save_paths + "install_isolated.tar.gz", extract_path)

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 上传ros固件
@admin_bp.route('/upload_ros_firmware', methods=['POST'])
def upload_ros_firmware():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        f = request.files['file']
        save_paths = os.environ.get("LYH_CONFIG") + "/"
        f.save(save_paths + f.filename)
        extract_path = os.environ.get("LYH_CONFIG") + "/../../ros_ws/"
        del_files(extract_path + "install_isolated")
        un_tar(save_paths + f.filename, extract_path)

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e

        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 上传驱动板固件
@admin_bp.route('/upload_drive_firmware', methods=['POST'])
def upload_drive_firmware():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        f = request.files['file']

        save_paths = os.environ.get("LYH_CONFIG") + "/"
        f.save(save_paths + f.filename)

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 重启机器人
@admin_bp.route('/restart_robot', methods=['POST'])
def restart_robot():
    import threading

    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        mode = request.values.get("mode")

        ret1 = ssh_shutdown(username="lyric", param="-r", mode=int(mode))
        ret2 = ssh_shutdown(username="apq", param="-r", mode=int(mode))
        if ret1 or ret2:
            response = json.dumps(data)
            return response, 200, {"Content-Type": "application/json"}
        else:
            data["msg"] = "restart error!"
            data["code"] = 500
            response = json.dumps(data)
            return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 上传地图列表
@admin_bp.route('/upload_map_list', methods=['POST'])
@auth
def upload_map_list():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        save_paths = os.environ.get("LYH_CONFIG") + "/map/"

        uploaded_files = request.files.getlist("file")

        for file in uploaded_files:
            if file and allowed_map_file(file.filename):

                filename = secure_filename(file.filename)
                file.save(save_paths + filename)
            else:
                data["msg"] = "you sent an error type file!"
                data["code"] = 500
                response = json.dumps(data)
                return response, 500, {"Content-Type": "application/json"}

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 上传音乐列表
@admin_bp.route('/upload_music_list', methods=['POST'])
def upload_music_list():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        save_paths = os.environ.get("LYH_CONFIG") + "/music/"

        uploaded_files = request.files.getlist("file")

        for file in uploaded_files:
            if file and allowed_music_file(file.filename):

                filename = secure_filename(file.filename)
                file.save(save_paths + filename)
            else:
                data["msg"] = "you sent an error type file!"
                data["code"] = 500
                response = json.dumps(data)
                return response, 500, {"Content-Type": "application/json"}

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 恢复ros_config.yaml初始化
@admin_bp.route('/initialization_ros_config', methods=['POST'])
def initialization_ros_config():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        config_file = os.path.dirname(os.path.abspath(__file__)) + "/config/ros_config.yaml"
        save_paths = os.environ.get("LYH_CONFIG") + "/"
        ret = copyfile(config_file, save_paths)
        # 错误处理
        if ret != "":
            data["msg"] = ret
            data["code"] = 500
            response = json.dumps(data)

            return response, 500, {"Content-Type": "application/json"}

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 下载ros_config.yaml:
@admin_bp.route('/download_ros_config', methods=['GET'])
def download_ros_config():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        download_paths = os.environ.get("LYH_CONFIG") + "/"
        file_name = "ros_config.yaml"
        path = download_paths + file_name
        return send_file(path)

    except BaseException as e:
        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


@admin_bp.route('/upload_ros_config', methods=['POST'])
def upload_ros_config():
    data = {
        "msg": "ok",
        "code": 0
    }
    try:
        f = request.files['file']
        if f.filename == "ros_config.yaml":
            save_paths = os.environ.get("LYH_CONFIG") + "/"
            f.save(save_paths + "ros_config.yaml")

            response = json.dumps(data)
            return response, 200, {"Content-Type": "application/json"}
        else:
            data["code"] = 500
            data["msg"] = "you send an error filename!"
            response = json.dumps(data)
            return response, 500, {"Content-Type": "application/json"}

    except BaseException as e:
        # print e

        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# 查看slam地图
@admin_bp.route('/slam_map')
@auth
def slam_map():
    return render_template('admin/slam_map.html')


# 操作当前地图
@admin_bp.route('/map_manager')
def map_manager():
    return render_template('admin/map_manager.html')


@admin_bp.route('/get_map_data', methods=['GET'])
def get_map_data():
    import json
    import requests
    data = {}
    try:
        req_type = request.args.get('type')  # 请求类型
        if req_type == "get_slam_data":
            data = requests.get("http://192.168.1.98:9997/api/v2/vehicles/maps/get/2022-09-17-16_04_29").json()
        elif req_type == "get_pointCloud":
            data = requests.get("http://192.168.1.98:9997/api/v2/vehicles/maps/get/2022-09-17-16_04_29").json()
        elif req_type == "get_robotState":
            data = requests.get("http://192.168.1.98:9997/api/v2/vehicles/maps/get/2022-09-17-16_04_29").json()
        elif req_type == "get_using_map":
            states = requests.get("http://192.168.1.98:9997/api/v2/vehicles/maps/get/2022-09-17-16_04_29").json()
            data = requests.get("http://192.168.1.98:9997/api/v2/vehicles/maps/get/2022-09-17-16_04_29/get/" + str(
                states["data"]["msgContent"]["mapId"])).json()
            temp = {
                "x": states["data"]["msgContent"]["x"],
                "y": states["data"]["msgContent"]["y"],
                "theta": states["data"]["msgContent"]["theta"]
            }
            data["data"]["robotPose"] = temp
        else:
            data = {"code": 500, "msg": "can not find the type!"}

        response = json.dumps(data)
        return response, 200, {"Content-Type": "application/json"}

    except Exception as e:
        # print e

        data["msg"] = str(e)
        data["code"] = 500
        response = json.dumps(data)

        return response, 500, {"Content-Type": "application/json"}


# # 上传ros_config.yaml
# @admin_bp.route('/upload_music_list', methods=['POST'])
# def upload_music_list():
#     data = {
#         "msg": "ok",
#         "code": 0
#     }
#     try:
#         save_paths = os.environ.get("LYH_CONFIG") + "/music/"
#
#         uploaded_files = request.files.getlist("file")
#
#         for file in uploaded_files:
#             if file and allowed_music_file(file.filename):
#
#                 filename = secure_filename(file.filename)
#                 file.save(save_paths + filename)
#             else:
#                 data["msg"] = "you sent an error type file!"
#                 data["code"] = 500
#                 response = json.dumps(data)
#                 return response, 500, {"Content-Type": "application/json"}
#
#         response = json.dumps(data)
#         return response, 200, {"Content-Type": "application/json"}
#
#     except BaseException as e:
#         # print e
#         data["msg"] = str(e)
#         data["code"] = 500
#         response = json.dumps(data)
#
#         return response, 500, {"Content-Type": "application/json"}


######### 修改 #################
# 用户展示
@admin_bp.route('/admin_user_list', methods=['GET', 'POST'])
@auth
def admin_user_list():
    # 获取所有的用户
    user_queryset = User.query.filter().all()
    username = session.get('username')
    is_ad = is_admin(username=username)
    return render_template('admin/admin_do.html', user_queryset=user_queryset, is_admin=is_ad)


# 编辑用户
@admin_bp.route('/edit_user/<int:id>', methods=['GET', 'POST'])
@auth
def edit_user(id):
    # 根据id查询到数据,进行修改
    user_obj = User.query.get(id)
    if request.method == 'GET':
        return render_template('admin/edit_user.html', user_obj=user_obj)
    # 修改
    username = request.form.get('username')
    phone = request.form.get('phone')
    is_delete = request.form.get('is_delete')
    is_admin = request.form.get('is_admin')
    # 保存
    user_obj.username = username
    user_obj.phone = phone
    user_obj.is_admin = int(is_admin)
    user_obj.is_delete = int(is_delete)
    db.session.commit()
    url_path = url_for('admin.admin_user_list')
    return redirect(url_path)


# 删除用户
# 编辑用户
@admin_bp.route('/delete_user/<int:id>', methods=['GET', 'POST'], endpoint='delete_user')
@auth
def delete_user(id):
    # 根据id查询到数据,进行修改
    user_obj = User.query.get(id)
    user_obj.is_delete = True
    db.session.commit()
    url_path = url_for('admin.admin_user_list')
    return redirect(url_path)


# 创建用户
@admin_bp.route('/add_user', methods=['GET', 'POST'])
@auth
def add_user():
    # 根据id查询到数据,进行修改
    if request.method == 'GET':
        return render_template('admin/add_user.html')
    # 修改
    username = request.form.get('username')
    phone = request.form.get('phone')
    password = request.form.get('password')
    is_delete = request.form.get('is_delete')
    is_admin = request.form.get('is_admin')
    user_obj = User()
    # 保存
    user_obj.username = username
    user_obj.phone = phone
    user_obj.password = md5(password)[0:20]
    user_obj.is_admin = int(is_admin)
    user_obj.is_delete = int(is_delete)
    db.session.add(user_obj)
    db.session.commit()
    url_path = url_for('admin.admin_user_list')
    return redirect(url_path)


@admin_bp.route('/test', methods=['GET', 'POST'])
@auth
def test():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/test.html', username=username, is_admin=is_ad)
    # 进行存数据库
    ret = request.files
    if not ret:
        print('这里是恢复ROS固件初始化.')
    if request.files.get('file_ros'):
        # 获取上传的ROS固件
        ros = request.files.get('file_ros')
        ros_name = ros.filename
        # 存放的路径
        path = basedir + "\\static\\r_files\\ros\\"
        # 图片path和名称组成图片的保存路径
        file_path = path + ros_name
        # 保存文件
        ros.save(file_path)
        mysql_path = '/static/r_files/ros/' + ros_name
        # 路径存数据库
        ros_obj = UpdateRobotFirmwareRos()
        ros_obj.ros_name = ros_name
        ros_obj.ros_path = mysql_path
        # 保存数据库
        db.session.add(ros_obj)
        db.session.commit()
        return redirect(url_for('admin.admin_index'))
        # 文件存服务器，或者存云仓库(cos(腾讯对象存储)/oss(阿里对象存储)/七牛云)
    if request.files.get('file_drive'):
        # 获取上传的上传驱动板固件
        drive = request.files.get('file_drive')
        drive_name = drive.filename
        # 存放的路径
        path = basedir + "\\static\\r_files\\ros\\"
        # 图片path和名称组成图片的保存路径
        file_path = path + drive_name
        # 保存文件
        drive.save(file_path)
        mysql_path = '/static/r_files/drive/' + drive_name
        # 路径存数据库
        drive_obj = UpdateRobotFirmwareDrive()
        drive_obj.drive_name = drive_name
        drive_obj.drive_path = mysql_path
        # 保存数据库
        db.session.add(drive_obj)
        db.session.commit()
        # 路径存数据库
        # 文件存服务器，或者存云仓库(cos(腾讯对象存储)/oss(阿里对象存储)/七牛云)
        return redirect(url_for('admin.admin_index'))
    if request.form.get('mode'):
        # 重启机器人
        pass
    return render_template('admin/test.html', username=username)


@admin_bp.route('/test2', methods=['GET', 'POST'])
@auth
def test2():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/test2.html', username=username, is_admin=is_ad)


# 机器人地图
@admin_bp.route('/test3', methods=['GET', 'POST'])
@auth
def test3():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/test3.html', username=username, is_admin=is_ad)

@admin_bp.route('/testmap', methods=['GET', 'POST'])
@auth
def testmap():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/testmap.html', username=username, is_admin=is_ad)


@admin_bp.route('/testslam_map', methods=['GET', 'POST'])
@auth
def testslam_map():
    username = session.get('username')
    is_ad = is_admin(username=username)
    if request.method == 'GET':
        return render_template('admin/testslam_map.html', username=username, is_admin=is_ad)

